package local.michel.util;

import java.awt.EventQueue;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.SpringLayout;
import javax.swing.JProgressBar;

import javax.swing.SwingWorker;

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JTextField;

import org.apache.log4j.Logger;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Lock;


import javax.swing.SwingUtilities;

import local.michel.util.Sorter;


public class UserComparePics {

	private JFrame frame;

	private static ConcurrentLinkedQueue<PicAction> actionQueue;

	protected Sorter sorter;

	private boolean result;

	Lock preloading;

	PicAction currentPicAction = null; 
	BufferedImage picLeft = null;
	BufferedImage picRight = null;
	private JLabel LeftImageLabel;
	private JLabel RightImageLabel;
	private JTextField textField;
	private JTextField textField_1;
	private JProgressBar progressBar;
	private JButton btnStart;
	private JButton btnStop;

	static Logger logger = Logger.getLogger(UserComparePics.class);

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					UserComparePics window = new UserComparePics();
					window.frame.setVisible(true);

					//s.start();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public UserComparePics() {

		initialize();

		sorter = new Sorter();
		sorter.registerGui(this);

		actionQueue = new ConcurrentLinkedQueue<PicAction>();
	}

	public void addAction(PicAction a) {
		logger.debug("Action added: " + a.toString());
		actionQueue.add(a);

		progressBar.setMaximum(1000);
		progressBar.setValue(actionQueue.size());

		if ((picLeft == null) && (picRight == null)) {
			logger.debug("first adding of pics");
			showNextPic();
		}

		logger.debug("Check preloading...");
		new SwingWorker() {
			@Override
			protected Object doInBackground() throws Exception {
				if (preloading.tryLock()) {
					try {
						logger.debug("Preload-Worker started!");
						preloadImages();
					}
					finally {
						preloading.unlock();
					}
				}
				return null;
			}
		}.execute();
	}

	protected void preloadImages() {
		for (PicAction a : actionQueue) {
			if (a.hasImages() == false) {
				a.loadImages();
			}
		}
	}

	protected void setPics(PicAction a) {
		logger.debug("SetPics " + a.toString());
		currentPicAction = a;
		if (a.hasImages() == false) {
			a.loadImages();
		}
		picLeft = a.getSourceImage();
		picRight = a.getDestImage();
		getTextFieldSrc().setText(a.getSource().getAbsolutePath());
		getTextFieldDest().setText(a.getDest().getAbsolutePath());
		setPics();
	}


	protected void setPics() {
		getLeftImageLabel().setIcon(new ImageIcon(picLeft.getScaledInstance(LeftImageLabel.getWidth(), 
				-1, java.awt.Image.SCALE_FAST)));
		getRightImageLabel().setIcon(new ImageIcon(picRight.getScaledInstance(RightImageLabel.getWidth(), 
				-1, java.awt.Image.SCALE_FAST)));
	}


	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 699, 571);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JPanel panel_2 = new JPanel();

		LeftImageLabel = new JLabel("New label");
		LeftImageLabel.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				System.out.println("componentResized JLABEL LEFT : " + e.getComponent().getWidth() 
						+ "," + e.getComponent().getHeight());
				if (picLeft != null)
					((JLabel) e.getComponent()).setIcon(new ImageIcon(picLeft.getScaledInstance(e.getComponent().getWidth(), e.getComponent().getHeight(), 
							java.awt.Image.SCALE_FAST)));
			}
		});

		RightImageLabel = new JLabel("New label");
		RightImageLabel.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				System.out.println("componentResized JLABEL RIGHT : " + e.getComponent().getWidth() 
						+ "," + e.getComponent().getHeight());
				if (picRight != null)
					((JLabel) e.getComponent()).setIcon(new ImageIcon(picRight.getScaledInstance(e.getComponent().getWidth(), e.getComponent().getHeight(), 
							java.awt.Image.SCALE_FAST)));
			}
		});
		GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
		groupLayout.setHorizontalGroup(
				groupLayout.createParallelGroup(Alignment.TRAILING)
				.addGroup(groupLayout.createSequentialGroup()
						.addContainerGap()
						.addComponent(LeftImageLabel, GroupLayout.PREFERRED_SIZE, 320, Short.MAX_VALUE)
						.addGap(18)
						.addComponent(RightImageLabel, GroupLayout.PREFERRED_SIZE, 320, Short.MAX_VALUE)
						.addGap(41))
						.addGroup(Alignment.LEADING, groupLayout.createSequentialGroup()
								.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 683, GroupLayout.PREFERRED_SIZE)
								.addContainerGap(26, Short.MAX_VALUE))
				);
		groupLayout.setVerticalGroup(
				groupLayout.createParallelGroup(Alignment.TRAILING)
				.addGroup(groupLayout.createSequentialGroup()
						.addGap(3)
						.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
								.addComponent(LeftImageLabel, GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
								.addComponent(RightImageLabel, GroupLayout.PREFERRED_SIZE, 400, GroupLayout.PREFERRED_SIZE))
								.addGap(35)
								.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 95, GroupLayout.PREFERRED_SIZE))
				);
		SpringLayout sl_panel_2 = new SpringLayout();
		panel_2.setLayout(sl_panel_2);

		progressBar = new JProgressBar();
		sl_panel_2.putConstraint(SpringLayout.WEST, progressBar, 10, SpringLayout.WEST, panel_2);
		sl_panel_2.putConstraint(SpringLayout.SOUTH, progressBar, -10, SpringLayout.SOUTH, panel_2);
		panel_2.add(progressBar);

		JButton sameButton = new JButton("Same");
		sameButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println(e.getActionCommand());
				currentPicAction.setSame();
				sorter.addResult(currentPicAction);
				showNextPic();
			}
		});
		sl_panel_2.putConstraint(SpringLayout.WEST, sameButton, 33, SpringLayout.EAST, progressBar);
		sl_panel_2.putConstraint(SpringLayout.SOUTH, sameButton, -10, SpringLayout.SOUTH, panel_2);
		panel_2.add(sameButton);

		JButton differentButton = new JButton("Different");
		differentButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println(e.getActionCommand());
				currentPicAction.setDifferent();
				sorter.addResult(currentPicAction);
				showNextPic();
			}
		});
		sl_panel_2.putConstraint(SpringLayout.WEST, differentButton, 17, SpringLayout.EAST, sameButton);
		sl_panel_2.putConstraint(SpringLayout.SOUTH, differentButton, 0, SpringLayout.SOUTH, progressBar);
		panel_2.add(differentButton);

		textField = new JTextField();
		sl_panel_2.putConstraint(SpringLayout.NORTH, textField, 10, SpringLayout.NORTH, panel_2);
		sl_panel_2.putConstraint(SpringLayout.WEST, textField, 10, SpringLayout.WEST, panel_2);
		sl_panel_2.putConstraint(SpringLayout.EAST, textField, 330, SpringLayout.WEST, panel_2);
		panel_2.add(textField);
		textField.setColumns(10);

		textField_1 = new JTextField();
		sl_panel_2.putConstraint(SpringLayout.NORTH, textField_1, 10, SpringLayout.NORTH, panel_2);
		sl_panel_2.putConstraint(SpringLayout.WEST, textField_1, 17, SpringLayout.EAST, textField);
		sl_panel_2.putConstraint(SpringLayout.EAST, textField_1, 337, SpringLayout.EAST, textField);
		panel_2.add(textField_1);
		textField_1.setColumns(10);

		btnStart = new JButton("Start");
		sl_panel_2.putConstraint(SpringLayout.NORTH, btnStart, 0, SpringLayout.NORTH, sameButton);
		sl_panel_2.putConstraint(SpringLayout.EAST, btnStart, -131, SpringLayout.EAST, panel_2);
		btnStart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println("Start pressed.");
				new SwingWorker() {
					@Override
					protected Object doInBackground() throws Exception {
						System.out.println("Worker started!");
						sorter.start();
						return null;
					}
				}.execute();
				btnStart.setEnabled(false);
				btnStop.setEnabled(true);
			}
		});
		panel_2.add(btnStart);

		btnStop = new JButton("Stop");
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				sorter.stop();
				btnStart.setEnabled(true);
				btnStop.setEnabled(false);
			}
		});
		sl_panel_2.putConstraint(SpringLayout.WEST, btnStop, 14, SpringLayout.EAST, btnStart);
		sl_panel_2.putConstraint(SpringLayout.SOUTH, btnStop, 0, SpringLayout.SOUTH, progressBar);
		panel_2.add(btnStop);
		frame.getContentPane().setLayout(groupLayout);
	}

	protected void showNextPic() {
		logger.debug("Trying to show next pics");
		if (SwingUtilities.isEventDispatchThread()) {
			setPics(actionQueue.poll());
		} else {
			try {
				EventQueue.invokeAndWait(new Runnable() {
					@Override
					public void run() {
						setPics(actionQueue.poll());
					}
				});
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	protected JLabel getLeftImageLabel() {
		return LeftImageLabel;
	}
	protected JLabel getRightImageLabel() {
		return RightImageLabel;
	}

	public boolean getResult() {
		return this.result;
	}
	protected JProgressBar getProgressBar() {
		return progressBar;
	}
	protected JButton getBtnStop() {
		return btnStop;
	}
	protected JTextField getTextFieldSrc() {
		return textField;
	}
	protected JTextField getTextFieldDest() {
		return textField_1;
	}
}
